#include "frontend/terminate.h"
#include "kernel/vkey.h"
#include "kernel/tty.h"

#include<QKeyEvent>
#include<QPalette>
#include<QColor>
#include<QTimer>
#include<QMainWindow>

Terminate::Terminate(QWidget *parent):QWidget(parent){
    painter = new QPainter(this);
    isCursorShow = 1;

    initTtyList();
    curTty = ttyList[0];

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateCursor()));
    timer->start(650);

    setFocusPolicy(Qt::StrongFocus);
    installEventFilter(this);
}

void Terminate::paintEvent(QPaintEvent * ){
    painter->begin(this);
    painter->setPen(Qt::white);
    painter->setBackgroundMode(Qt::OpaqueMode);
    painter->setBackground(QBrush(QColor(48,10,36)));
    QFont font("Monospace");
    font.setPixelSize(17);
    painter->setFont(font);

    QFontMetrics metrics(font);
    cursorHeight = metrics.height();
    cursorWidth = metrics.width(QChar('Q'));

    int xpos = 0;
    int ypos = cursorHeight-metrics.descent()/2;
    Buff p = GetBuffer(curTty);
    int startRow = curTty->startRow;
    for(int i=startRow;i<TTY_ROW+startRow;i++){
        for(int j=0;j<TTY_COLUMN;j++){
            char c = p[i][j];
            QString s = QString(QChar(c));
            painter->drawText(xpos,ypos,s);
            xpos += cursorWidth;
        }
        ypos += cursorHeight;
        xpos = 0;
    }
    drawCursor(painter);
    painter->end();
}

void Terminate::drawCursor(QPainter *painter){
    int x = 0;
    int y = 0;
    Cursor cursor;
    GetCursor(curTty, &cursor);
    x = x + cursor.curColumn * cursorWidth;
    y = y + (cursor.curRow -curTty->startRow) * cursorHeight;

    if(isCursorShow){
        painter->setPen(Qt::white);
        painter->setBrush(QBrush(QColor(Qt::white)));
        isCursorShow = 0;
    }else{
        painter->setPen(QColor(48,10,36));
        painter->setBrush(QBrush(QColor(48,10,36)));
        isCursorShow = 1;
    }

    painter->drawRect(QRect(x,y,cursorWidth,cursorHeight));
}

void Terminate::updateCursor(){
    int x = 0;
    int y = 0;
    Cursor cursor;
    GetCursor(curTty, &cursor);
    x = x + cursor.curColumn * cursorWidth;
    y = y + (cursor.curRow -curTty->startRow)* cursorHeight;
    update(QRect(x,y,cursorWidth+1,cursorHeight+1));
}

void Terminate::initTtyList(){
    for(int i=0;i<TTY_NUM;i++){
        ttyList[i] = new Teletype;
        ttyList[i]->buffer = new TerminateBuffer;
        CreateTeletype(ttyList[i]);
    }
}

bool Terminate::eventFilter(QObject *, QEvent * event){
    QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);

    //1. filter arrows
    if(IsKeyArrow(keyEvent->key())){
        return true;
    }

    //2. filter F*
    if(IsKeyF(keyEvent->key()) && !IsKeyControlModifiers(keyEvent->modifiers())){
        return true;
    }

    //3. filter delete TODO
    if(IsKeyDelete(keyEvent->key())){
        return true;
    }

    if(IsKeyControl(keyEvent->key())){
        return true;
    }

    return false;
}

void Terminate::keyPressEvent(QKeyEvent *event){
    QString key = event->text();
    short k = (short)key.toStdString().c_str()[0];
    int modifiers = event->modifiers();


    if(isKeySwitchTty(event->key(),event->modifiers())){
        switch(event->key()){
        case Key_F1:
            curTty = ttyList[0];
            break;
        case Key_F2:
            curTty = ttyList[1];
            break;
        case Key_F3:
            curTty = ttyList[2];
            break;
        case Key_F4:
            curTty = ttyList[3];
            break;
        case Key_F5:
            curTty = ttyList[4];
            break;
        case Key_F6:
            curTty = ttyList[5];
            break;
        case Key_F7:
            curTty = ttyList[6];
            break;
        case Key_F8:
            curTty = ttyList[7];
            break;
        }
       repaint();
       return;
    }

    TeletypeKeyPressed(curTty,event->key(),k,modifiers);
    repaint();
    event->ignore();
}

Teletype* Terminate::GetTty(){
    return curTty;
}

Terminate::~Terminate()
{
    FreeTty(curTty);
}
